﻿Imports System.ComponentModel
Imports System.Linq.Expressions

Public Class VM_PublisherCardRecord
	Inherits AutomaticNotfiyPropertyChanged
	Implements IDisposable

	Dim workingRecord As PublisherCardData
	Dim db As New CongregationDataContainerLocal

	Public Property PublisherID As Long
		Get
			Return workingRecord.PublisherID
		End Get
		Set(value As Long)
			workingRecord.PublisherID = value
		End Set
	End Property

	Public Property ReportMonth As DateTime
		Get
			Return workingRecord.Month
		End Get
		Set(value As DateTime)
			workingRecord.Month = value.FirstOfTheMonth
		End Set
	End Property

	Public Property IsHistorical As Boolean
		Get
			Return workingRecord.IsHistorical
		End Get
		Set(value As Boolean)
			If IsHistorical AndAlso Not value Then
				'if it was historical and we're setting it to not-historical, then update the date of the record
				workingRecord.Entered = DateTime.UtcNow
			End If
			workingRecord.IsHistorical = value
			NotifyPropertyChanged()

		End Set
	End Property

	Public Property Books As Integer
		Get
			Return workingRecord.Books
		End Get
		Set(value As Integer)
			workingRecord.Books = value
			NotifyPropertyChanged()
		End Set
	End Property

	Public Property Brochures As Integer
		Get
			Return workingRecord.Brochures
		End Get
		Set(value As Integer)
			workingRecord.Brochures = value
			NotifyPropertyChanged()
		End Set
	End Property

	Public Property Hours As Decimal
		Get
			Return workingRecord.Hours
		End Get
		Set(value As Decimal)
			Dim adjustedHours As Decimal
			If IsAuxPioneer Or IsPioneer Then
				adjustedHours = Math.Truncate(value)
			Else
				adjustedHours = value
			End If
			workingRecord.Hours = adjustedHours
			NotifyPropertyChanged()
			NotifyPropertyChanged(Function(x) PioneerHours)
			NotifyPropertyChanged(Function(x) PioneerHoursFriendly)
		End Set
	End Property

	Public Property PioneerCreditHours As Integer
		Get
			Return If(IsPioneer, workingRecord.PioneerCreditHours, 0)
		End Get
		Set(value As Integer)
			workingRecord.PioneerCreditHours = value
			NotifyPropertyChanged()
			NotifyPropertyChanged(Function(x) PioneerHours)
			NotifyPropertyChanged(Function(x) PioneerHoursFriendly)
		End Set
	End Property

	Public ReadOnly Property PioneerHours As Integer
		Get
			Return Hours + PioneerCreditHours
		End Get
	End Property

	Public ReadOnly Property PioneerHoursFriendly As String
		Get
			If IsPioneer Then
				Return PioneerHours
			Else
				Return "N/A"
			End If
		End Get
	End Property

	Public Property Magazines As Integer
		Get
			Return workingRecord.Magazines
		End Get
		Set(value As Integer)
			workingRecord.Magazines = value
			NotifyPropertyChanged()
		End Set
	End Property

	Public Property ReturnVisits As Integer
		Get
			Return workingRecord.ReturnVisits
		End Get
		Set(value As Integer)
			workingRecord.ReturnVisits = value
			NotifyPropertyChanged()
		End Set
	End Property

	Public Property BibleStudies As Integer
		Get
			Return workingRecord.BibleStudies
		End Get
		Set(value As Integer)
			workingRecord.BibleStudies = value
			NotifyPropertyChanged()
		End Set
	End Property

	Public Property Remarks As String
		Get
			Return workingRecord.Remarks
		End Get
		Set(value As String)
			workingRecord.Remarks = value
			NotifyPropertyChanged()
		End Set
	End Property

	Public Property IsBaptized As Boolean
		Get
			Return workingRecord.IsBaptized
		End Get
		Set(value As Boolean)
			workingRecord.IsBaptized = value

			If Not IsBaptized Then
				workingRecord.IsAuxPioneer = False
				workingRecord.IsPioneer = False
				workingRecord.IsSpecialPioneer = False
				NotifyPropertyChanged(Me, Function(x) x.IsAuxPioneer)
				NotifyPropertyChanged(Me, Function(x) x.IsPioneer)
				NotifyPropertyChanged(Me, Function(x) x.IsSpecialPioneer)
			End If

			NotifyPropertyChanged()
			NotifyPropertyChanged(Me, Function(x) x.Status)
		End Set
	End Property

	Public Property IsPublisher As Boolean
		Get
			Return Not (IsAuxPioneer Or IsPioneer Or IsSpecialPioneer)
		End Get
		Set(value As Boolean)
			If value Then
				workingRecord.IsSpecialPioneer = False
				workingRecord.IsPioneer = False
				workingRecord.IsAuxPioneer = False
				NotifyPropertyChanged(Me, Function(x) x.IsSpecialPioneer)
				NotifyPropertyChanged(Me, Function(x) x.IsPioneer)
				NotifyPropertyChanged(Me, Function(x) x.IsAuxPioneer)
			End If

			NotifyPropertyChanged()
			NotifyPropertyChanged(Me, Function(x) x.Status)
		End Set
	End Property

	Public Property IsAuxPioneer As Boolean
		Get
			Return workingRecord.IsAuxPioneer
		End Get
		Set(value As Boolean)
			workingRecord.IsAuxPioneer = value

			If IsAuxPioneer Then
				workingRecord.IsBaptized = True
				workingRecord.IsPioneer = False
				workingRecord.IsSpecialPioneer = False
				NotifyPropertyChanged(Me, Function(x) x.IsBaptized)
				NotifyPropertyChanged(Me, Function(x) x.IsPioneer)
				NotifyPropertyChanged(Me, Function(x) x.IsSpecialPioneer)
			End If

			NotifyPropertyChanged()
			NotifyPropertyChanged(Me, Function(x) x.Status)
		End Set
	End Property

	Public Property IsPioneer As Boolean
		Get
			Return workingRecord.IsPioneer
		End Get
		Set(value As Boolean)
			workingRecord.IsPioneer = value

			If IsPioneer Then
				workingRecord.IsBaptized = True
				workingRecord.IsAuxPioneer = False
				workingRecord.IsSpecialPioneer = False
				NotifyPropertyChanged(Me, Function(x) x.IsBaptized)
				NotifyPropertyChanged(Me, Function(x) x.IsAuxPioneer)
				NotifyPropertyChanged(Me, Function(x) x.IsSpecialPioneer)
			End If

			NotifyPropertyChanged()
			NotifyPropertyChanged(Me, Function(x) x.Status)
		End Set
	End Property

	Public Property IsSpecialPioneer As Boolean
		Get
			Return workingRecord.IsSpecialPioneer
		End Get
		Set(value As Boolean)
			workingRecord.IsSpecialPioneer = value

			If IsSpecialPioneer Then
				workingRecord.IsBaptized = True
				workingRecord.IsAuxPioneer = False
				workingRecord.IsPioneer = False
				NotifyPropertyChanged(Me, Function(x) x.IsBaptized)
				NotifyPropertyChanged(Me, Function(x) x.IsAuxPioneer)
				NotifyPropertyChanged(Me, Function(x) x.IsPioneer)
			End If

			NotifyPropertyChanged()
			NotifyPropertyChanged(Me, Function(x) x.Status)
		End Set
	End Property

	Public ReadOnly Property Status As String
		Get
			'just return a string stating the status for the DataGridView
			Select Case True
				Case IsBaptized
					Select Case True
						Case IsAuxPioneer
							Return "Auxiliary Pioneer"
						Case IsPioneer
							Return "Pioneer"
						Case IsSpecialPioneer
							Return "Special Pioneer"
						Case Else
							Return "Baptized Publisher"
					End Select
				Case Else
					Return "Unbaptized Publisher"
			End Select
		End Get
	End Property

	Public ReadOnly Property IsReadOnly As Boolean
		Get
			If workingRecord.Entered = Date.MinValue Then
				'this is a blank record, so it isn't readonly
				Return False
			Else
				Return workingRecord.Reported
			End If

		End Get
	End Property

	Public Sub Save()
		If Not IsReadOnly Then
			'Dim db As New CongregationDataContainerLocal

			Dim updatableRecord = db.PublisherCardDatas.SingleOrDefault(Function(x) x.PublisherID = PublisherID And x.Month = ReportMonth)
			Dim myPublisher = db.PublisherDatas.Single(Function(x) x.PublisherID = PublisherID)

			If updatableRecord Is Nothing Then
				workingRecord.Entered = DateTime.UtcNow
				'if the month being saved has no hours or is in the future, save it as 'historical'
				If Hours > 0 AndAlso workingRecord.Month <= DateTime.UtcNow Then
					workingRecord.IsHistorical = IsHistorical
				Else
					workingRecord.IsHistorical = True
				End If
				db.PublisherCardDatas.AddObject(workingRecord)
			Else
				With updatableRecord
					'since the record is updatable, modify the date so that we can report it to the branch
					'non-updatable records should never get here because they would be read-only
					.Entered = DateTime.UtcNow
					.Books = Books
					.Brochures = Brochures
					If IsAuxPioneer Or IsPioneer Or IsSpecialPioneer Then
						.Hours = Int(Hours)
					Else
						.Hours = Hours
					End If
					.PioneerCreditHours = PioneerCreditHours
					.Magazines = Magazines
					.ReturnVisits = ReturnVisits
					.BibleStudies = BibleStudies
					.Remarks = Remarks
					.IsBaptized = IsBaptized
					.IsAuxPioneer = IsAuxPioneer
					.IsPioneer = IsPioneer
					.IsSpecialPioneer = IsSpecialPioneer
					'if the month being saved has no hours or is in the future, save it as 'historical'
					If Hours > 0 AndAlso .Month <= DateTime.UtcNow Then
						.IsHistorical = IsHistorical
					Else
						.IsHistorical = True
					End If
				End With
			End If

			db.SaveChanges()
		End If
	End Sub

	Public Sub Delete()
		If Not IsReadOnly Then
			'Using db As New CongregationDataContainerLocal

			Dim updatableRecord = db.PublisherCardDatas.SingleOrDefault(Function(x) x.PublisherID = PublisherID And x.Month = ReportMonth)

			If updatableRecord IsNot Nothing Then
				db.PublisherCardDatas.DeleteObject(workingRecord)
			End If

			db.SaveChanges()
			'End Using
		End If
	End Sub

	Public Sub New(PublisherID As Long, Month As DateTime)
		'Using db As New CongregationDataContainerLocal

		workingRecord = db.PublisherCardDatas.SingleOrDefault(Function(x) x.PublisherID = PublisherID And x.Month = Month)

		If workingRecord Is Nothing Then
			workingRecord = New PublisherCardData
			Dim workingPublisher As PublisherData = db.PublisherDatas.Single(Function(x) x.PublisherID = PublisherID)
			'populate default values
			Me.PublisherID = PublisherID
			ReportMonth = Month

			If workingPublisher.DateImmersed IsNot Nothing OrElse workingPublisher.PublisherCardDatas.Any(Function(x) x.IsBaptized) Then
				IsBaptized = True
			Else
				IsBaptized = False
			End If
			IsAuxPioneer = workingPublisher.IsRegAuxPioneer
			IsPioneer = workingPublisher.IsPioneer
			IsSpecialPioneer = workingPublisher.IsSpecialPioneer
			IsHistorical = If(ReportMonth < ConfigPropertyKeys.ReportLastSubmitted.FirstOfTheMonth, True, False)
		End If
		'End Using
	End Sub

	'Public Shared Sub ChangeRemark(publisherID As Long, report As DateTime, oldRemark As String, newRemark As String)
	'	Using db As New CongregationDataContainerLocal
	'		Dim publisher = db.PublisherCardDatas.SingleOrDefault(Function(x) x.PublisherID = publisherID AndAlso x.Month = report)

	'		If publisher IsNot Nothing AndAlso publisher.Remarks = oldRemark Then
	'			publisher.Remarks = newRemark
	'			db.SaveChanges()
	'		End If
	'	End Using
	'End Sub

	Public Sub ChangeRemark(oldRemark As String, newRemark As String)
		If workingRecord.Remarks = oldRemark Then
			workingRecord.Remarks = newRemark
			db.SaveChanges()
		End If

		'Using db As New CongregationDataContainerLocal
		'Dim publisher = db.PublisherCardDatas.SingleOrDefault(Function(x) x.PublisherID = PublisherID AndAlso x.Month = report)

		'If publisher IsNot Nothing AndAlso publisher.Remarks = oldRemark Then
		'	publisher.Remarks = newRemark
		'	db.SaveChanges()
		'End If
		'End Using
	End Sub

	'Public Shared Sub ChangePioneerCreditHours(publisherID As Long, report As DateTime, oldCreditHours As Integer, newCreditHours As Integer)
	'	Using db As New CongregationDataContainerLocal
	'		Dim publisher = db.PublisherCardDatas.SingleOrDefault(Function(x) x.PublisherID = publisherID AndAlso x.Month = report AndAlso x.PioneerCreditHours = oldCreditHours AndAlso x.IsPioneer)

	'		If publisher IsNot Nothing Then
	'			publisher.PioneerCreditHours = newCreditHours
	'			db.SaveChanges()
	'		End If
	'	End Using
	'End Sub

	Public Sub ChangePioneerCreditHours(oldCreditHours As Integer, newCreditHours As Integer)
		If workingRecord.PioneerCreditHours = oldCreditHours Then
			workingRecord.PioneerCreditHours = newCreditHours
			db.SaveChanges()
		End If

		'Using db As New CongregationDataContainerLocal
		'	Dim publisher = db.PublisherCardDatas.SingleOrDefault(Function(x) x.PublisherID = publisherID AndAlso x.Month = report AndAlso x.PioneerCreditHours = oldCreditHours AndAlso x.IsPioneer)

		'	If publisher IsNot Nothing Then
		'		publisher.PioneerCreditHours = newCreditHours
		'		db.SaveChanges()
		'	End If
		'End Using
	End Sub

#Region "IDisposable Support"
	Private disposedValue As Boolean ' To detect redundant calls

	' IDisposable
	Protected Overridable Sub Dispose(disposing As Boolean)
		If Not Me.disposedValue Then
			If disposing Then
				db.Dispose()
				' TODO: dispose managed state (managed objects).
			End If

			' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
			' TODO: set large fields to null.
		End If
		Me.disposedValue = True
	End Sub

	' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
	'Protected Overrides Sub Finalize()
	'    ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
	'    Dispose(False)
	'    MyBase.Finalize()
	'End Sub

	' This code added by Visual Basic to correctly implement the disposable pattern.
	Public Sub Dispose() Implements IDisposable.Dispose
		' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
		Dispose(True)
		GC.SuppressFinalize(Me)
	End Sub
#End Region

End Class
